package com.danciyixue.boot.dcyx.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.danciyixue.boot.dcyx.mapper.UnitTestRecordsMapper;
import com.danciyixue.boot.dcyx.service.UnitTestRecordsService;
import com.danciyixue.boot.dcyx.model.entity.UnitTestRecords;
import com.danciyixue.boot.dcyx.model.form.UnitTestRecordsForm;
import com.danciyixue.boot.dcyx.model.query.UnitTestRecordsQuery;
import com.danciyixue.boot.dcyx.model.vo.UnitTestRecordsVO;
import com.danciyixue.boot.dcyx.converter.UnitTestRecordsConverter;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.danciyixue.boot.core.security.util.SecurityUtils;

/**
 * 单元测试记录服务实现类
 *
 * @author youlaitech
 * @since 2025-06-15 16:33
 */
@Service
@DS("dcyx")
@RequiredArgsConstructor
public class UnitTestRecordsServiceImpl extends ServiceImpl<UnitTestRecordsMapper, UnitTestRecords> implements UnitTestRecordsService {

    private final UnitTestRecordsConverter unitTestRecordsConverter;

    /**
    * 获取单元测试记录分页列表
    *
    * @param queryParams 查询参数
    * @return {@link IPage<UnitTestRecordsVO>} 单元测试记录分页列表
    */
    @Override
    public IPage<UnitTestRecordsVO> getUnitTestRecordsPage(UnitTestRecordsQuery queryParams) {
        // 参数校验
        Assert.notNull(queryParams, "查询参数不能为空");

        // 如果是客户端用户，强制设置当前用户ID，确保只能查询自己的记录
        if (SecurityUtils.isClientUser()) {
            Long currentUserId = SecurityUtils.getUserId();
            Assert.notNull(currentUserId, "用户未登录");
            queryParams.setUserId(currentUserId);
        }

        // 如果传入了programId，需要验证参数的有效性
        if (ObjectUtil.isNotNull(queryParams.getProgramId())) {
            Assert.isTrue(queryParams.getProgramId() > 0, "教材ID必须大于0");
        }

        Page<UnitTestRecordsVO> pageVO = this.baseMapper.getUnitTestRecordsPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }
    
    /**
     * 获取单元测试记录表单数据
     *
     * @param id 单元测试记录ID
     * @return 单元测试记录表单数据
     */
    @Override
    public UnitTestRecordsForm getUnitTestRecordsFormData(Long id) {
        UnitTestRecords entity = this.getById(id);
        return unitTestRecordsConverter.toForm(entity);
    }
    
    /**
     * 新增单元测试记录
     *
     * @param formData 单元测试记录表单对象
     * @return 是否新增成功
     */
    @Override
    public boolean saveUnitTestRecords(UnitTestRecordsForm formData) {
        UnitTestRecords entity = unitTestRecordsConverter.toEntity(formData);
        return this.save(entity);
    }
    
    /**
     * 更新单元测试记录
     *
     * @param id   单元测试记录ID
     * @param formData 单元测试记录表单对象
     * @return 是否修改成功
     */
    @Override
    public boolean updateUnitTestRecords(Long id,UnitTestRecordsForm formData) {
        UnitTestRecords entity = unitTestRecordsConverter.toEntity(formData);
        return this.updateById(entity);
    }
    
    /**
     * 删除单元测试记录
     *
     * @param ids 单元测试记录ID，多个以英文逗号(,)分割
     * @return 是否删除成功
     */
    @Override
    public boolean deleteUnitTestRecordss(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的单元测试记录数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

    /**
     * 保存或更新单元测试记录
     *
     * @param userId 用户ID
     * @param unitId 单元ID
     * @param score 测试得分
     * @param timeSpent 测试耗时(秒)
     * @param isEnd 是否完成(0-未完成, 1-完成)
     * @return 是否保存成功
     */
    @Override
    public boolean saveOrUpdateUnitTestRecord(Long userId, Long unitId, Integer score, Integer timeSpent, Integer isEnd) {
        // 参数校验
        Assert.notNull(userId, "用户ID不能为空");
        Assert.notNull(unitId, "单元ID不能为空");
        Assert.notNull(score, "测试得分不能为空");
        Assert.notNull(timeSpent, "测试耗时不能为空");
        Assert.notNull(isEnd, "完成状态不能为空");

        // 根据 userId 和 unitId 查询现有记录
        UnitTestRecords existingRecord = this.baseMapper.findByUserIdAndUnitId(userId, unitId);

        if (existingRecord != null) {
            // 如果存在则更新
            return updateExistingUnitTestRecord(existingRecord, score, timeSpent, isEnd);
        } else {
            // 不存在则插入
            return insertNewUnitTestRecord(userId, unitId, score, timeSpent, isEnd);
        }
    }

    /**
     * 更新现有单元测试记录
     */
    private boolean updateExistingUnitTestRecord(UnitTestRecords existingRecord, Integer score, Integer timeSpent, Integer isEnd) {
        existingRecord.setScore(score);
        existingRecord.setTimeSpent(timeSpent);
        existingRecord.setIsEnd(isEnd);
        return this.updateById(existingRecord);
    }

    /**
     * 插入新单元测试记录
     */
    private boolean insertNewUnitTestRecord(Long userId, Long unitId, Integer score, Integer timeSpent, Integer isEnd) {
        UnitTestRecords unitTestRecord = new UnitTestRecords();
        unitTestRecord.setUserId(userId);
        unitTestRecord.setUnitId(unitId);
        unitTestRecord.setScore(score);
        unitTestRecord.setTimeSpent(timeSpent);
        unitTestRecord.setIsEnd(isEnd);
        return this.save(unitTestRecord);
    }

}
